#!/usr/bin/env python3
"""
Matter温控器属性读取器
使用chip-tool读取Matter设备温控器的所有相关属性
"""

import subprocess
import sys
import json
import time
from typing import Dict, List, Optional, Tuple
from thermostat_parser import ThermostatParser, ThermostatData, format_thermostat_data


class ThermostatReader:
    """温控器属性读取器"""
    
    def __init__(self, chip_tool_path: str = "./chip-tool"):
        self.chip_tool_path = chip_tool_path
        self.parser = ThermostatParser()
        
        # 定义要读取的温控器属性列表
        # 格式: (chip_tool属性名, 描述)
        self.thermostat_attributes = [
            ("local-temperature", "本地温度"),
            ("abs-min-heat-setpoint-limit", "绝对最小加热设定点限制"),
            ("abs-max-heat-setpoint-limit", "绝对最大加热设定点限制"),
            ("abs-min-cool-setpoint-limit", "绝对最小制冷设定点限制"),
            ("abs-max-cool-setpoint-limit", "绝对最大制冷设定点限制"),
            ("occupied-cooling-setpoint", "占用制冷设定点"),
            ("occupied-heating-setpoint", "占用加热设定点"),
            ("min-heat-setpoint-limit", "最小加热设定点限制"),
            ("max-heat-setpoint-limit", "最大加热设定点限制"),
            ("min-cool-setpoint-limit", "最小制冷设定点限制"),
            ("max-cool-setpoint-limit", "最大制冷设定点限制"),
            ("min-setpoint-dead-band", "最小设定点死区"),
            ("control-sequence-of-operation", "控制操作序列"),
            ("system-mode", "系统模式"),
            ("thermostat-running-state", "温控器运行状态")
        ]
        
        # 定义要读取的风扇控制属性列表
        self.fan_control_attributes = [
            ("fan-mode", "风扇模式"),
            ("fan-mode-sequence", "风扇模式序列")
        ]
    
    def read_thermostat_attribute(self, attribute: str, endpoint: int = 1, node_id: int = 1) -> Optional[str]:
        """
        读取单个温控器属性
        
        Args:
            attribute: 属性名
            endpoint: 端点号
            node_id: 节点ID
            
        Returns:
            chip-tool输出或None（如果失败）
        """
        try:
            cmd = [
                self.chip_tool_path,
                "thermostat", "read", attribute,
                str(node_id), str(endpoint)
            ]
            
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                timeout=30
            )
            
            if result.returncode == 0:
                return result.stdout
            else:
                print(f"读取温控器属性 {attribute} 失败: {result.stderr}")
                return None
                
        except subprocess.TimeoutExpired:
            print(f"读取温控器属性 {attribute} 超时")
            return None
        except Exception as e:
            print(f"读取温控器属性 {attribute} 时发生错误: {e}")
            return None
    
    def read_fan_control_attribute(self, attribute: str, fan_endpoint: int = 2, node_id: int = 1) -> Optional[str]:
        """
        读取单个风扇控制属性
        
        Args:
            attribute: 属性名
            fan_endpoint: 风扇控制端点号（通常为2）
            node_id: 节点ID
            
        Returns:
            chip-tool输出或None（如果失败）
        """
        try:
            cmd = [
                self.chip_tool_path,
                "fancontrol", "read", attribute,
                str(node_id), str(fan_endpoint)
            ]
            
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                timeout=30
            )
            
            if result.returncode == 0:
                return result.stdout
            else:
                print(f"读取风扇控制属性 {attribute} 失败: {result.stderr}")
                return None
                
        except subprocess.TimeoutExpired:
            print(f"读取风扇控制属性 {attribute} 超时")
            return None
        except Exception as e:
            print(f"读取风扇控制属性 {attribute} 时发生错误: {e}")
            return None
    
    def read_all_attributes(self, thermostat_endpoint: int = 1, fan_endpoint: int = 2, node_id: int = 1, 
                           delay: float = 0.5, include_fan: bool = True) -> Tuple[str, Dict[str, str]]:
        """
        读取所有温控器和风扇控制属性
        
        Args:
            thermostat_endpoint: 温控器端点号
            fan_endpoint: 风扇控制端点号
            node_id: 节点ID
            delay: 每次读取之间的延迟（秒）
            include_fan: 是否包含风扇控制属性
            
        Returns:
            (合并的输出, 属性读取结果字典)
        """
        combined_output = ""
        results = {}
        total_attrs = len(self.thermostat_attributes) + (len(self.fan_control_attributes) if include_fan else 0)
        
        print(f"开始读取属性 (温控器端点: {thermostat_endpoint}, 风扇端点: {fan_endpoint}, 节点: {node_id})")
        print("=" * 70)
        
        # 读取温控器属性
        for i, (attr_name, description) in enumerate(self.thermostat_attributes, 1):
            print(f"[{i:2d}/{total_attrs:2d}] {description:<25} ({attr_name})", end=' ')
            
            output = self.read_thermostat_attribute(attr_name, thermostat_endpoint, node_id)
            
            if output:
                combined_output += output + "\n"
                results[attr_name] = output.strip()
                print("✅ 成功")
            else:
                results[attr_name] = ""
                print("❌ 失败")
            
            # 添加延迟避免设备过载
            if i < len(self.thermostat_attributes):
                time.sleep(delay)
        
        # 读取风扇控制属性
        if include_fan:
            for i, (attr_name, description) in enumerate(self.fan_control_attributes, 1):
                total_i = len(self.thermostat_attributes) + i
                print(f"[{total_i:2d}/{total_attrs:2d}] {description:<25} ({attr_name})", end=' ')
                
                output = self.read_fan_control_attribute(attr_name, fan_endpoint, node_id)
                
                if output:
                    combined_output += output + "\n"
                    results[attr_name] = output.strip()
                    print("✅ 成功")
                else:
                    results[attr_name] = ""
                    print("❌ 失败")
                
                # 添加延迟避免设备过载
                if i < len(self.fan_control_attributes):
                    time.sleep(delay)
        
        print("=" * 70)
        print("🎉 所有属性读取完成!")
        
        return combined_output, results
    
    def parse_and_format(self, combined_output: str) -> Optional[ThermostatData]:
        """
        解析合并的输出并格式化显示
        
        Args:
            combined_output: chip-tool的合并输出
            
        Returns:
            解析后的温控器数据或None
        """
        if not combined_output.strip():
            print("没有有效的输出数据可解析")
            return None
        
        try:
            data = self.parser.parse_output(combined_output)
            return data
        except Exception as e:
            print(f"解析输出时发生错误: {e}")
            return None
    
    def save_raw_output(self, output: str, filename: str = "thermostat_raw_output.txt"):
        """保存原始输出到文件"""
        try:
            with open(filename, 'w', encoding='utf-8') as f:
                f.write(output)
            print(f"📁 原始输出已保存到: {filename}")
        except Exception as e:
            print(f"保存原始输出失败: {e}")
    
    def save_json_data(self, data: ThermostatData, filename: str = "thermostat_data.json"):
        """保存解析后的数据为JSON格式"""
        try:
            # 填充实际数据
            data_dict = {
                'local_temperature_celsius': data.local_temperature,
                'heating_limits': {
                    'absolute_min': data.abs_min_heat_setpoint_limit,
                    'absolute_max': data.abs_max_heat_setpoint_limit,
                    'min': data.min_heat_setpoint_limit,
                    'max': data.max_heat_setpoint_limit,
                    'occupied_setpoint': data.occupied_heating_setpoint
                },
                'cooling_limits': {
                    'absolute_min': data.abs_min_cool_setpoint_limit,
                    'absolute_max': data.abs_max_cool_setpoint_limit,
                    'min': data.min_cool_setpoint_limit,
                    'max': data.max_cool_setpoint_limit,
                    'occupied_setpoint': data.occupied_cooling_setpoint
                },
                'system_settings': {
                    'min_setpoint_dead_band': data.min_setpoint_dead_band,
                    'control_sequence_of_operation': data.control_sequence_of_operation,
                    'system_mode': data.system_mode,
                    'thermostat_running_state': data.thermostat_running_state
                },
                'fan_control': {
                    'fan_mode': data.fan_mode,
                    'fan_mode_sequence': data.fan_mode_sequence
                },
                'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
            }
            
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(data_dict, f, indent=2, ensure_ascii=False)
            print(f"📁 JSON数据已保存到: {filename}")
        except Exception as e:
            print(f"保存JSON数据失败: {e}")


def main():
    """主函数"""
    print("🌡️ Matter温控器属性读取器")
    print("=" * 50)
    
    # 参数配置
    thermostat_endpoint = 1
    fan_endpoint = 2
    node_id = 1
    delay = 0.5
    include_fan = True
    
    # 检查命令行参数
    if len(sys.argv) > 1:
        try:
            node_id = int(sys.argv[1])
        except ValueError:
            print("❌ 错误: 节点ID必须是数字")
            sys.exit(1)
    
    if len(sys.argv) > 2:
        try:
            thermostat_endpoint = int(sys.argv[2])
        except ValueError:
            print("❌ 错误: 温控器端点号必须是数字")
            sys.exit(1)
    
    if len(sys.argv) > 3:
        try:
            fan_endpoint = int(sys.argv[3])
        except ValueError:
            print("❌ 错误: 风扇端点号必须是数字")
            sys.exit(1)
    
    # 检查是否包含风扇控制
    if len(sys.argv) > 4 and sys.argv[4].lower() in ['false', 'no', '0']:
        include_fan = False
    
    print("⚙️ 配置参数:")
    print(f"  📍 节点ID: {node_id}")
    print(f"  🌡️ 温控器端点号: {thermostat_endpoint}")
    print(f"  🌀 风扇控制端点号: {fan_endpoint}")
    print(f"  ⏱️ 读取延迟: {delay}秒")
    print(f"  🔄 包含风扇控制: {include_fan}")
    print()
    
    # 创建读取器实例
    reader = ThermostatReader()
    
    # 读取所有属性
    combined_output, results = reader.read_all_attributes(thermostat_endpoint, fan_endpoint, node_id, delay, include_fan)
    
    if combined_output:
        # 保存原始输出
        reader.save_raw_output(combined_output)
        
        # 解析数据
        print("\n🔍 解析温控器数据...")
        thermostat_data = reader.parse_and_format(combined_output)
        
        if thermostat_data:
            # 格式化显示
            print("\n" + "="*60)
            print(format_thermostat_data(thermostat_data))
            print("="*60)
            
            # 保存JSON数据
            reader.save_json_data(thermostat_data)
            
            # 显示读取统计
            all_attributes = reader.thermostat_attributes.copy()
            if include_fan:
                all_attributes.extend(reader.fan_control_attributes)
                
            print(f"\n📊 读取统计:")
            successful_reads = sum(1 for output in results.values() if output)
            failed_reads = len(all_attributes) - successful_reads
            
            print(f"  ✅ 成功: {successful_reads}/{len(all_attributes)}")
            if failed_reads > 0:
                print(f"  ❌ 失败: {failed_reads}/{len(all_attributes)}")
            else:
                print("  🎉 全部读取成功!")
                
        else:
            print("❌ 解析数据失败")
    else:
        print("❌ 没有读取到任何数据")


if __name__ == "__main__":
    main()
